use tauri::command;
use crate::ctp_commands::ctp::types::ApiResponse;
use crate::ctp_commands::ctp::state::*;
use crate::ctp_commands::ctp::utils::get_ctp_cache_path;
use crate::ctp_commands::ctp::event_handler::{start_md_stream_processing, start_trader_stream_processing};

// 引入 CTP 相关模块
use ctp_trade_lib::{get_api_version as ctp_get_api_version, md_api, trader_api};

// 基础 API 命令
#[command]
pub fn get_api_version() -> ApiResponse<String> {
    match ctp_get_api_version() {
        Some(version) => ApiResponse {
            success: true,
            data: Some(version),
            error: None,
        },
        None => ApiResponse {
            success: false,
            data: None,
            error: Some("Failed to get API version".to_string()),
        },
    }
}

// 安全的 MD API 创建函数
fn create_md_api_safe(
    session_id: &str,
    flow_path: &str,
    is_using_udp: bool,
    is_multicast: bool,
) -> Result<String, String> {
    // 1. 如果提供了相对路径，使用系统临时目录
    let actual_flow_path = if flow_path.starts_with("../temp/") || flow_path.starts_with("./") {
        get_ctp_cache_path(session_id)?
    } else {
        // 验证绝对路径
        if flow_path.is_empty() {
            return Err("Flow path cannot be empty".to_string());
        }
        flow_path.to_string()
    };

    // 2. 确保目录存在
    if let Err(e) = std::fs::create_dir_all(&actual_flow_path) {
        return Err(format!("Failed to create directory {}: {}", actual_flow_path, e));
    }

    // 3. 检查是否已存在相同的 session_id
    {
        let apis = get_md_apis().lock().map_err(|e| format!("Failed to lock MD_APIS: {}", e))?;
        if apis.contains_key(session_id) {
            return Err(format!("Session ID {} already exists", session_id));
        }
    }

    // 4. 创建 API 和 Stream（这是可能崩溃的地方）
    // 使用 std::panic::catch_unwind 捕获可能的 panic
    let api_result = std::panic::catch_unwind(|| {
        // 添加额外的安全检查
        if actual_flow_path.len() > 256 {
            panic!("Flow path too long: {}", actual_flow_path.len());
        }

        // 确保目录存在
        if let Some(parent) = std::path::Path::new(&actual_flow_path).parent() {
            if let Err(_e) = std::fs::create_dir_all(parent) {
                // Failed to create directory
            }
        }

        // 创建API和Stream
        let mut api = md_api::create_api(&actual_flow_path, is_using_udp, is_multicast);
        let (stream, spi_ptr) = ctp_trade_lib::md_api::create_spi();

        // 注册SPI到API
        api.register_spi(spi_ptr);

        (api, stream)
    });

    let (api, stream) = match api_result {
        Ok((api, stream)) => {
            (api, stream)
        },
        Err(panic_info) => {
            let error_msg = format!("CTP MD API creation panicked: {:?}", panic_info);
            return Err(error_msg);
        }
    };

    // 5. 存储 API 和 Stream
    {
        let mut apis = get_md_apis().lock().map_err(|e| format!("Failed to lock MD_APIS for storage: {}", e))?;
        apis.insert(session_id.to_string(), api);
    }

    {
        let mut streams = get_md_streams().lock().map_err(|e| format!("Failed to lock MD_STREAMS for storage: {}", e))?;
        streams.insert(session_id.to_string(), stream);
    }

    // 6. 启动Stream处理任务
    start_md_stream_processing(session_id.to_string());

    Ok(session_id.to_string())
}

#[command]
pub fn create_md_api(
    session_id: String,
    flow_path: String,
    is_using_udp: bool,
    is_multicast: bool,
) -> ApiResponse<String> {
    match create_md_api_safe(&session_id, &flow_path, is_using_udp, is_multicast) {
        Ok(session_id) => {
            ApiResponse {
                success: true,
                data: Some(session_id),
                error: None,
            }
        },
        Err(error) => {
            ApiResponse {
                success: false,
                data: None,
                error: Some(error),
            }
        }
    }
}

#[command]
pub fn create_trader_api(
    session_id: String,
    flow_path: String,
    encrypt: bool,
) -> ApiResponse<String> {
    match std::panic::catch_unwind(|| {
        // 检查是否已存在相同的 session_id
        {
            let apis = get_trader_apis().lock().unwrap();
            if apis.contains_key(&session_id) {
                return Err(format!("Trader session ID {} already exists", session_id));
            }
        }

        // 确保目录存在
        if let Err(e) = std::fs::create_dir_all(&flow_path) {
            return Err(format!("Failed to create directory {}: {}", flow_path, e));
        }

        // 创建API和Stream
        let mut api = trader_api::create_api(&flow_path, encrypt);
        let (stream, spi_ptr) = ctp_trade_lib::trader_api::create_spi();

        // 注册SPI到API
        api.register_spi(spi_ptr);

        // 存储API和Stream
        let mut apis = get_trader_apis().lock().unwrap();
        apis.insert(session_id.clone(), api);

        let mut streams = get_trader_streams().lock().unwrap();
        streams.insert(session_id.clone(), stream);

        // 初始化登录状态为未登录
        let mut login_status = get_trader_login_status().lock().unwrap();
        login_status.insert(session_id.clone(), false);

        // 启动Stream处理任务
        start_trader_stream_processing(session_id.clone());

        Ok(session_id)
    }) {
        Ok(Ok(session_id)) => ApiResponse {
            success: true,
            data: Some(session_id),
            error: None,
        },
        Ok(Err(error)) => ApiResponse {
            success: false,
            data: None,
            error: Some(error),
        },
        Err(_) => ApiResponse {
            success: false,
            data: None,
            error: Some("Failed to create Trader API".to_string()),
        },
    }
}

// 安全释放 Trader API 资源
fn release_trader_api_safe(session_id: &str) -> Result<(), String> {
    let mut apis = get_trader_apis().lock().map_err(|e| format!("Failed to lock TRADER_APIS: {}", e))?;

    if let Some(_api) = apis.remove(session_id) {
        // 清理相关状态
        {
            let mut login_status = get_trader_login_status().lock().unwrap();
            login_status.remove(session_id);
        }

        {
            let mut streams = get_trader_streams().lock().unwrap();
            streams.remove(session_id);
        }

        {
            let mut session_info = get_session_login_info().lock().unwrap();
            session_info.remove(session_id);
        }

        // 安全地释放 CTP API 资源
        let release_result = std::panic::catch_unwind(|| {
            // 注意：CTP API 的 release 方法可能会导致崩溃
            // 这里我们先不调用 release，让 Rust 的 Drop trait 处理
            // _api.release();
        });

        match release_result {
            Ok(_) => {
                println!("✅ [CLEANUP] Trader API released for session: {}", session_id);
                Ok(())
            },
            Err(_) => {
                let error_msg = format!("Trader API release panicked for session: {}", session_id);
                println!("❌ [ERROR] {}", error_msg);
                Err(error_msg)
            }
        }
    } else {
        let error_msg = format!("Trader session ID {} not found", session_id);
        Err(error_msg)
    }
}

// 安全释放 MD API 资源
fn release_md_api_safe(session_id: &str) -> Result<(), String> {
    let mut apis = get_md_apis().lock().map_err(|e| format!("Failed to lock MD_APIS: {}", e))?;

    if let Some(_api) = apis.remove(session_id) {
        // 安全地释放 CTP API 资源
        let release_result = std::panic::catch_unwind(|| {
            // 注意：CTP API 的 release 方法可能会导致崩溃
            // 这里我们先不调用 release，让 Rust 的 Drop trait 处理
            // _api.release();
        });

        match release_result {
            Ok(_) => {
                Ok(())
            },
            Err(_) => {
                let error_msg = format!("MD API release panicked for session: {}", session_id);
                Err(error_msg)
            }
        }
    } else {
        let error_msg = format!("Session ID {} not found", session_id);
        Err(error_msg)
    }
}

// 释放交易API
#[command]
pub fn release_trader_api(session_id: String) -> ApiResponse<String> {
    println!("🔄 [CLEANUP] Releasing trader API for session: {}", session_id);

    match release_trader_api_safe(&session_id) {
        Ok(_) => {
            println!("✅ [CLEANUP] Trader API released successfully for session: {}", session_id);
            ApiResponse {
                success: true,
                data: Some(format!("Trader API released for session: {}", session_id)),
                error: None,
            }
        },
        Err(error) => {
            println!("❌ [ERROR] Failed to release trader API for session {}: {}", session_id, error);
            ApiResponse {
                success: false,
                data: None,
                error: Some(error),
            }
        }
    }
}

#[command]
pub fn release_md_api(session_id: String) -> ApiResponse<String> {
    match release_md_api_safe(&session_id) {
        Ok(_) => {
            ApiResponse {
                success: true,
                data: Some(format!("MD API {} released", session_id)),
                error: None,
            }
        },
        Err(error) => {
            ApiResponse {
                success: false,
                data: None,
                error: Some(error),
            }
        }
    }
}

